package liuyao.webutils.controller;

import com.alibaba.fastjson.JSONObject;
import liuyao.utils.http.HTTPClient;
import liuyao.utils.http.HTTPResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/utils")
@CrossOrigin
public class UtilController {

    private static final String[] IP_HEADERS = {
            "x-forwarded-for",
            "X-Real-IP",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_CLIENT_IP",
            "HTTP_X_FORWARDED_FOR"
    };

    @Autowired
    ThreadPoolExecutor allAcceptExecutor;

    @GetMapping("/getIP")
    public String getIp(HttpServletRequest request) {
        return getRemoteIp(request);
    }


    /**
     * 获取IP地址
     *
     * 使用Nginx等反向代理软件， 则不能通过request.getRemoteAddr()获取IP地址
     * 如果使用了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP地址，
     * X-Forwarded-For中第一个非 unknown 的有效IP字符串，则为真实IP地址
     */
    public static String getRemoteIp(HttpServletRequest request) {
        String header = request.getHeader("X-Forwarded-For");
        if (null == header || header.isEmpty()) return request.getRemoteAddr();
        String[] split = header.split(",");
        for (String ip : split) if (!ip.isEmpty() && !ip.equals("unknown")) return ip;
        return request.getRemoteAddr();
    }

    @GetMapping("/checkUrls")
    public String getIp(String[] urls) {
        JSONObject json = new JSONObject();
        if (null == urls || urls.length == 0) return json.toJSONString();
        CountDownLatch latch = new CountDownLatch(urls.length);
        for (String url : urls) {
            allAcceptExecutor.submit(() -> {
                HTTPResponse resp = null;
                try {
                    resp = HTTPClient.httpHead(URLDecoder.decode(url, StandardCharsets.UTF_8.name()));
                } catch (Exception e) {
                    json.put(url, String.format("HTTP/1.1 500 %s", e.getMessage()));
                    latch.countDown();
                    return;
                }
                StringBuilder sb = new StringBuilder(resp.statusLine).append("\r\n");
                resp.headers.forEach((k, v) -> {
                    sb.append(k).append(": ").append(v).append("\r\n");
                });
                json.put(url, sb);
                latch.countDown();
            });
        }
        try {
            latch.await(30, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return json.toJSONString();
    }

}
